home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / vbdatabs / ffind.cpp < prev    next >
C/C++ Source or Header  |  1999-03-26  |  17KB  |  538 lines

  1. // ------------------------------- //
  2. // -------- Start of File -------- //
  3. // ------------------------------- //
  4. // ----------------------------------------------------------- // 
  5. // C++ Source Code File Name: ffind.cpp 
  6. // Compiler Used: MSVC40, DJGPP 2.7.2.1, GCC 2.7.2.1, HP CPP 10.24
  7. // Produced By: gaer@nhc.noaa.gov
  8. // File Creation Date: 03/09/1999 
  9. // Date Last Modified: 03/26/1999
  10. // ----------------------------------------------------------- // 
  11. // ------------- Program description and details ------------- // 
  12. // ----------------------------------------------------------- // 
  13. /*
  14. THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
  15. THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE
  16. IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE,
  17. YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR
  18. CORRECTION.
  19.   
  20. This program is used to find and replace strings in a file.
  21. */
  22. // ----------------------------------------------------------- // 
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <stdlib.h>
  26. #include <fstream.h>
  27. #include <iostream.h>
  28. #include "strutil.h"
  29. #include "ustring.h"
  30. #include "dllist.h"
  31.  
  32. // Version number and program name
  33. const double FFindVersionNumber = 1031.102;
  34. const char *ProgramName = "ffind";
  35.  
  36. // Program globals
  37. const int MAX_LINE = 1024;   // Maximum characters per line
  38. char *open_file = 0;         // Name of file currently opened
  39. unsigned num_files = 0;      // Total number of files processed
  40. char *string_to_find = 0;    // String to find in each line
  41. int find_string = 0;         // Find specified string flag
  42. int find_all = 0;            // Find all occurrences
  43. int check_case = 1;          // Case sensitive/insensitive compare flag
  44. unsigned num_matches = 0;    // Total number of matches found
  45. int cat_file = 0;            // Concatenate file flag
  46. char *string_to_replace = 0; // String to replace
  47. char *string_to_insert = 0;  // String to insert
  48. int replacing_string = 0;    // Replace string flag
  49. int num_replaced = 0;        // Number of strings replaced
  50. int replacing_line = 0;      // Replace line flag
  51. int inserting_string = 0;    // Insert line flag
  52. int append_lines = 1;        // Append lines connected with a backslash
  53. int num_processed = 0;       // Number of string processed per file
  54.  
  55. void HelpMessage(const char *program_name, const double version_number)
  56. {
  57.   char vbuffer[255];
  58.   sprintf(vbuffer, "%.3f", version_number);
  59.   cout << endl;
  60.   cout << program_name << " program version "
  61.        << vbuffer  << endl;
  62.   cout << "Usage: " << program_name << " [switches] iofile.txt " << endl; 
  63.   cout << "Switches: " << endl;
  64.   cout << "          -a = Do not append lines connected by a backslash"
  65.        << endl;
  66.   cout << "          -c = Concatenate file to stdout." << endl;
  67.   cout << "          -f = Find first occurrence of specified string: "
  68.        << "-f\"string\"" << endl;
  69.   cout << "          -F = Find all occurrences of specified string: "
  70.        << "-F\"string\"" << endl;
  71.   cout << "          -i = Perform case insensitive compare." << endl;
  72.   cout << endl;
  73.   cout << "          -R -W = Replace all occurrences of a string in a file."
  74.        << endl;
  75.   cout << "          Usage: -R\"string\" -W\"replacement\"" << endl;
  76.   cout << endl;
  77.   cout << "          -L -W = Replace entire line after the specifed string."
  78.        << endl;
  79.   cout << "          Usage: -L\"string\" -W\"replacement\"" << endl;
  80.   cout << endl;
  81.   cout << "          -I -W = Insert a line after the specifed string."
  82.        << endl;
  83.   cout << "          Usage: -I\"string\" -W\"insert\"" << endl;
  84.   cout << endl;
  85.   exit(0);
  86. }
  87.  
  88. int ProcessArgs(char *arg)
  89. {
  90.   switch(arg[1]) {
  91.     case 'a':
  92.       append_lines = 0;
  93.       break;
  94.       
  95.     case 'c':
  96.       cat_file = 1;
  97.       break;
  98.  
  99.     case 'f':                
  100.       if(arg[2] == '\0') {
  101.     cerr << endl;
  102.     cerr << "You must enter a string following the -f option." << endl;
  103.     cerr << "Example usage: " << ProgramName << " -f\"string\"" << endl; 
  104.     cerr << endl;
  105.     return 0;
  106.       }
  107.       find_string = 1;
  108.       find_all = 0;
  109.       replacing_line = 0;  
  110.       replacing_string = 0;  
  111.       inserting_string = 0;
  112.       string_to_find = arg+2;
  113.       break;
  114.  
  115.     case 'F':                
  116.       if(arg[2] == '\0') {
  117.     cerr << endl;
  118.     cerr << "You must enter a string following the -F option." << endl;
  119.     cerr << "Example usage: " << ProgramName << " -F\"string\"" << endl; 
  120.     cerr << endl;
  121.     return 0;
  122.       }
  123.       find_string = 1;
  124.       find_all =1;
  125.       replacing_line = 0;  
  126.       replacing_string = 0;  
  127.       inserting_string = 0;
  128.       string_to_find = arg+2;
  129.       break;
  130.  
  131.     case 'i':
  132.       check_case = 0;
  133.       break;
  134.       
  135.     case 'R':
  136.       if(arg[2] == '\0') {
  137.     cerr << endl;
  138.     cerr << "You must enter a string following the -R option." << endl;
  139.     cerr << "Example usage: " << ProgramName << " -R\"string\"" << endl; 
  140.     cerr << endl;
  141.     return 0;
  142.       }
  143.       string_to_replace = arg+2;
  144.       replacing_string = 1;  
  145.       replacing_line = 0;
  146.       inserting_string = 0;
  147.       find_string = 0;
  148.       find_all = 0;
  149.       break;
  150.  
  151.     case 'L':
  152.       if(arg[2] == '\0') {
  153.     cerr << endl;
  154.     cerr << "You must enter a string following the -L option." << endl;
  155.     cerr << "Example usage: " << ProgramName << " -L\"string\"" << endl; 
  156.     cerr << endl;
  157.     return 0;
  158.       }
  159.       string_to_replace = arg+2;
  160.       replacing_line = 1;  
  161.       replacing_string = 0;
  162.       inserting_string = 0;
  163.       find_string = 0;
  164.       find_all = 0;
  165.       break;
  166.  
  167.     case 'I':
  168.       if(arg[2] == '\0') {
  169.     cerr << endl;
  170.     cerr << "You must enter a string following the -I option." << endl;
  171.     cerr << "Example usage: " << ProgramName << " -I\"string\"" << endl; 
  172.     cerr << endl;
  173.     return 0;
  174.       }
  175.       string_to_replace = arg+2;
  176.       inserting_string = 1;
  177.       replacing_line = 0;  
  178.       replacing_string = 0;  
  179.       find_string = 0;
  180.       find_all = 0;
  181.       break;
  182.  
  183.     case 'W':
  184.       if(arg[2] == '\0') {
  185.     cerr << endl;
  186.     cerr << "You must enter a string following the -W option." << endl;
  187.     cerr << "Example usage: " << ProgramName << " -W\"string\"" << endl; 
  188.     cerr << endl;
  189.     return 0;
  190.       }
  191.  
  192.       if(string_to_replace == 0) {
  193.     cerr << endl;
  194.     cerr << "The -W option must be used with the -R, -L, or -I option."
  195.          << endl;
  196.     cerr << "Usage: -R\"string\" -W\"replacement\"" << endl;
  197.     cerr << endl;
  198.     return 0;
  199.       }
  200.  
  201.       string_to_insert = arg+2;
  202.       break;
  203.       
  204.     default:
  205.       cerr << endl;
  206.       cerr << "Unknown switch " << arg << endl;
  207.       cerr << "Exiting..." << endl;
  208.       cerr << endl;
  209.       return 0;
  210.   }
  211.   arg[0] = '\0';
  212.   return 1; // All command line arguments were valid
  213. }
  214.  
  215. int ProcessTextFile(fstream &iofile, ostream &stream)
  216. {
  217.   char LineBuffer[MAX_LINE];
  218.   char rawLineBuffer[MAX_LINE];
  219.   UString LineData;
  220.   UString appendLineBuffer;
  221.   DLList<UString> list;
  222.   int i, j, rv, offset = 0;
  223.   unsigned long line_number = 0;
  224.   
  225.   while(!iofile.eof()) { // Read in the file line by line
  226.  
  227.     // Clear the buffers
  228.     for(i = 0; i < MAX_LINE; i++) LineBuffer[i] = '\0';
  229.     for(i = 0; i < MAX_LINE; i++) rawLineBuffer[i] = '\0';
  230.     LineData.DeleteAt(0, LineData.length());
  231.     offset = 0; // Reset string offset
  232.     
  233.     iofile.getline(rawLineBuffer, MAX_LINE);
  234.     line_number++;
  235.         
  236.     // Filter each line of text
  237.     for(i = 0, j = 0; i < MAX_LINE; i++) {
  238.       if((rawLineBuffer[i] == '\r') || (rawLineBuffer[i] == '\n')) break;
  239.       LineBuffer[j++] = rawLineBuffer[i];
  240.     }
  241.  
  242.     // Detect backslashes used to mark the continuation of a line
  243.     if((LineBuffer[strlen(LineBuffer)-1] == '\\') && (append_lines == 1)) {
  244.       appendLineBuffer += LineBuffer;
  245.       appendLineBuffer += '\n'; // Insert LF after the backslash 
  246.       continue;  // Goto the top of loop and append next line
  247.     }
  248.     if(appendLineBuffer.length() > 0) { // Append the next line
  249.       appendLineBuffer += LineBuffer;
  250.       LineData = appendLineBuffer;
  251.       appendLineBuffer.DeleteAt(0, appendLineBuffer.length());
  252.     }
  253.     else
  254.       L